package org.pangu.client.dubbo;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.dubbo.rpc.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

public class TagInvoker<T> implements Invoker<T> {
    private static final Logger logger = LoggerFactory.getLogger(TagInvoker.class);

    private Invoker<T> invoker;

    public TagInvoker(Invoker<T> invoker) {
        this.invoker = invoker;
    }

    @Override
    public Class<T> getInterface() {
        return invoker.getInterface();
    }

    @Override
    public Result invoke(Invocation invocation) throws RpcException {
        if (StringUtils.hasText(DubboProperties.consumerTag)) {
            RpcContext context = RpcContext.getContext();
            if (!context.getAttachments().containsKey(Constants.TAG_KEY)) {
                context.setAttachment(Constants.TAG_KEY, DubboProperties.consumerTag);
            }
        }
        if (DubboProperties.consumerTagforce != null && DubboProperties.consumerTagforce) {
            RpcContext context = RpcContext.getContext();
            if (!context.getAttachments().containsKey(Constants.FORCE_USE_TAG)) {
                context.setAttachment(Constants.FORCE_USE_TAG, "true");
            }
        }
        Result result;
        try {
            result = invoker.invoke(invocation);
        } catch (RpcException e) {
            String message = e.getMessage();
            if (message != null && message.contains("No provider available for")) {
                RpcContext context = RpcContext.getContext();
                String consumerTag = context.getAttachments().get(Constants.TAG_KEY);
                if (consumerTag != null) {
                    logger.error("No provider available with Tag : {}", consumerTag);
                } else if ("true".equals(context.getAttachments().get(Constants.FORCE_USE_TAG))) {
                    logger.error("'tag-force' equals true, you must specify a tag name");
                }
            }
            throw e;
        }
        return result;
    }

    @Override
    public URL getUrl() {
        return invoker.getUrl();
    }

    @Override
    public boolean isAvailable() {
        return invoker.isAvailable();
    }

    @Override
    public void destroy() {
        invoker.destroy();
    }
}
